package com.hbisoft.pickit;

import ohos.aafwk.ability.AbilitySlice;
import ohos.app.Context;
import ohos.utils.net.Uri;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.logging.Level;
import java.util.logging.Logger;

public class PickiT implements CallBackTask {
    private Context context;
    private final PickiTCallbacks pickiTCallbacks;
    private boolean isDriveFile = false;
    private boolean isFromUnknownProvider = false;
    private DownloadAsyncTask asyntask;
    private boolean unknownProviderCalledBefore = false;
    private AbilitySlice mAbility;

    public PickiT(Context context, PickiTCallbacks listener, AbilitySlice ability) {
        this.context = context;
        this.pickiTCallbacks = listener;
        mAbility = ability;
    }

    public void getPath(Uri uri) {
        String returnedPath;
        Logger.getLogger("qri").log(Level.INFO, "returnUriIs" + uri);
        // Drive file was selected
        if (isOneDrive(uri) || isDropBox(uri) || isGoogleDrive(uri)) {
            isDriveFile = true;
            downloadFile(uri);
        }
        // Local file was selected
        else {
            returnedPath = Utils.getRealPathFromURI_API19(context, uri);
            if (returnedPath != null && returnedPath.length() > 0) {
                Logger.getLogger("RETURNED-").log(Level.INFO, returnedPath);
            } else {
                Logger.getLogger("RETURNED-").log(Level.INFO, "路径为空");
            }

            // Get the file extension
            // 未发现MimeType对应的Api使用,暂时做屏蔽处理。
            // final MimeTypeMap mime = MimeTypeMap.getSingleton();
            // String subStringExtension = String.valueOf(returnedPath).substring(String.valueOf(returnedPath).lastIndexOf(".") + 1);
            //  String extensionFromMime = null;
            //  try {
            //     extensionFromMime = mime.getExtensionFromMimeType(DataAbilityHelper.creator(context).getType(uri));
            //  } catch (DataAbilityRemoteException e) {
            //     e.printStackTrace();
            //  }

            // Path is null
            if (returnedPath == null || returnedPath.equals("")) {
                // This can be caused by two situations
                // 1. The file was selected from a third party app and the data column returned null (for example EZ File Explorer)
                // Some file providers (like EZ File Explorer) will return a URI as shown below:
                // content://es.fileexplorer.filebrowser.ezfilemanager.externalstorage.documents/document/primary%3AFolderName%2FNameOfFile.mp4
                // When you try to read the _data column, it will return null, without trowing an exception
                // In this case the file need to copied/created a new file in the temporary folder
                // 2. There was an error
                // In this case call PickiTonCompleteListener and get/provide the reason why it failed

                // We first check if it was called before, avoiding multiple calls
                if (!unknownProviderCalledBefore) {
                    unknownProviderCalledBefore = true;
                    if (uri.getScheme() != null && uri.getScheme().equals("content")) {
                        // Then we check if the _data colomn returned null
                        if (Utils.errorReason() != null && Utils.errorReason().equals("dataReturnedNull")) {
                            isFromUnknownProvider = true;
                            // Copy the file to the temporary folder
                            downloadFile(uri);
                            return;
                        } else if (Utils.errorReason() != null && Utils.errorReason().contains("column '_data' does not exist")) {
                            isFromUnknownProvider = true;
                            // Copy the file to the temporary folder
                            downloadFile(uri);
                            return;
                        } else if (Utils.errorReason() != null && Utils.errorReason().equals("uri")) {
                            isFromUnknownProvider = true;
                            // Copy the file to the temporary folder
                            downloadFile(uri);
                            return;
                        }
                    }
                }
                // Else an error occurred, get/set the reason for the error
                pickiTCallbacks.pickiTonCompleteListener(returnedPath, false, false, false, Utils.errorReason());
            }
            // Path is not null
            else {
                // This can be caused by two situations
                // 1. The file was selected from an unknown provider (for example a file that was downloaded from a third party app)
                // 2. getExtensionFromMimeType returned an unknown mime type for example "audio/mp4"
                //
                // When this is case we will copy/write the file to the temp folder, same as when a file is selected from Drive etc.
                // We provide a name by getting the text after the last "/"
                // Remember if the extension can't be found, it will not be added, but you will still be able to use the file
                //Todo: Add checks for unknown file extensions

                // 未发现MimeType对应的Api使用,暂时做屏蔽处理。
                // if (!subStringExtension.equals("jpeg") && !subStringExtension.equals(extensionFromMime) && uri.getScheme() != null && uri.getScheme().equals("content")) {
                //     isFromUnknownProvider = true;
                //     downloadFile(uri);
                //     return;
                // }

                // Path can be returned, no need to make a "copy"
                pickiTCallbacks.pickiTonCompleteListener(returnedPath, false, false, true, "");
            }
        }
    }

    // Create a new file from the Uri that was selected
    private void downloadFile(Uri uri) {
        asyntask = new DownloadAsyncTask(uri, context, this, mAbility);
        asyntask.execute();
    }

    // End the "copying" of the file
    public void cancelTask() {
        if (asyntask != null) {
            asyntask.cancel(true);
            deleteTemporaryFile(context);
        }
    }

    // was Local File Selected
    public boolean wasLocalFileSelected(Uri uri) {
        return !isDropBox(uri) && !isGoogleDrive(uri) && !isOneDrive(uri);
    }

    // Check different providers
    private boolean isDropBox(Uri uri) {
        return String.valueOf(uri).toLowerCase().contains("content://com.dropbox.");
    }

    private boolean isGoogleDrive(Uri uri) {
        return String.valueOf(uri).toLowerCase().contains("com.google.android.apps");
    }

    private boolean isOneDrive(Uri uri) {
        return String.valueOf(uri).toLowerCase().contains("com.microsoft.skydrive.content");
    }

    // PickiT callback Listeners
    @Override
    public void pickiTonUriReturned() {
        pickiTCallbacks.pickiTonUriReturned();
    }

    @Override
    public void pickiTonPreExecute() {
        pickiTCallbacks.pickiTonStartListener();
    }

    @Override
    public void pickiTonProgressUpdate(int progress) {
        pickiTCallbacks.pickiTonProgressUpdate(progress);
    }

    @Override
    public void pickiTonPostExecute(String path, boolean wasDriveFile, boolean wasSuccessful, String reason) {
        unknownProviderCalledBefore = false;
        if (wasSuccessful) {
            if (isDriveFile) {
                pickiTCallbacks.pickiTonCompleteListener(path, true, false, true, "");
            } else if (isFromUnknownProvider) {
                pickiTCallbacks.pickiTonCompleteListener(path, false, true, true, "");
            }
        } else {
            if (isDriveFile) {
                pickiTCallbacks.pickiTonCompleteListener(path, true, false, false, reason);
            } else if (isFromUnknownProvider) {
                pickiTCallbacks.pickiTonCompleteListener(path, false, true, false, reason);
            }
        }
    }

    // Delete the temporary folder
    public void deleteTemporaryFile(Context context) {
        File folder = context.getExternalFilesDir("Temp");
        if (folder != null) {
            if (deleteDirectory(folder)) {
                Logger.getLogger("PickiT ").log(Level.INFO, "deleteDirectory was called");
            }
        }
    }

    private boolean deleteDirectory(File path) {
        if (path.exists()) {
            File[] files = path.listFiles();
            if (files == null) {
                return false;
            }
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    deleteFile(file);
                }
            }
        }
        boolean isdelete = deleteFile(path);
        return isdelete;
    }

    private boolean deleteFile(File file) {
        boolean isdelete = false;
        try {
            Files.delete(file.getAbsoluteFile().toPath());
            isdelete = true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return isdelete;
    }

}
